#include "CollisionEngine.hpp"

list<CollidableObject*> CollisionEngine::m_projectiles;
list<CollidableObject*> CollisionEngine::m_objects;

void CollisionEngine::update() {
	// iterator variables
	list<CollidableObject*>::iterator it;
	list<CollidableObject*>::iterator it2;

	// updating 
	for (it = m_projectiles.begin(); it != m_projectiles.end(); it++) 
		(*it)->updateHitBoxes();
	for (it2 = m_objects.begin(); it2 != m_objects.end(); it2++) 
		(*it2)->updateHitBoxes();
	int j = 0;

	list<CollidableObject*>::iterator it_tmp;
	// collision detection
	for (it = m_projectiles.begin(); it != m_projectiles.end();) {
		HitBoxes* hb1 = ((*it)->getUpdatedHitBoxes());
		CollidableObject* launcher = (*it)->getLauncher();
		vec3 pointv = hb1->corner();
		if (pointv.z < 0) {
			// calling special projectile ground collision call back
			// with string for describing nature of ground
			(*it)->groundCollisionCallBack("ground");
			it = deleteProjectile(*it);
			delete hb1;
			continue;
		};

		it_tmp = it;
		bool deleteFlag = false;
		for (it2 = m_objects.begin(); it2 != m_objects.end(); it2++) {
			if ((*it2)->getUpdatedHitBoxes()->collideHitBoxes(*hb1) && (*it2) != launcher) {
				it_tmp++;
				// collision call back call
				(*it2)->collisionCallBack(*it);
				(*it)->collisionCallBack(*it2);
				// the projectile will be destructed by its collisionCallBack
				// so we have to stop the loop for this projectile
				deleteFlag = true;
				break;
			} 				
		};
		if (deleteFlag) {
			it = deleteProjectile(*it);
		} else it++;
		delete hb1;
	}
}; 
